package tmp

/**
 * Created by Administrator on 2015/3/13.
 */
object ScalaOverView extends App {
  def p(any: Any) = println(any)
  def exists[T](xs: Array[T], p: T => Boolean): Boolean = {
    var i = 0
    while (i < xs.length && !p(xs(i))) i += 1
    i < xs.length
  }

  def forall[T](xs: Array[T], p: T => Boolean) = {
    //    def not_p(x: T) = !p(x)
    //    !exists(xs, not_p)
    !exists(xs, (row: T) => !p(row))
  }

  def hasZeroRaw(matrix: Array[Array[Int]]) =
    matrix exists (row => row forall (0 == _))

  val list = List(1, 2, 3, 1, 2, 3, 1, 2, 1, 1)

  val results = list.map {
    _ match {
      case 1 => Some(1)
      case 2 => None
      case 3 => Some(2)
      case _ => None
    }
  }
  p(results.flatten.size)

  p("-=-=-=-=-=Product Demo=-=-=-=-=-")

  case class Person(name: String, age: Int)

  val person: Product = Person("Dean", 29)

  p("person.productArity:" + person.productArity)
  p("person.productElement(0):" + person.productElement(0))
  p("person.productElement(1):" + person.productElement(1))
  person.productIterator foreach p
  p("person.productPrefix:" + person.productPrefix)

  p("Array(1,2) == Array(1,2):" + (Array(1, 2) == Array(1, 2)))
  p("Array(1,2) sameElements Array(1,2):" + (Array(1, 2) sameElements Array(1, 2)))

  p("List(1,2) == List(1,2):" + (List(1, 2) == List(1, 2)))
  p("List(1,2) sameElements List(1,2):" + (List(1, 2) sameElements List(1, 2)))

  val list2 = scala.collection.mutable.LinkedList(1)
  p(s"LikedList:$list2")
  list2.append(scala.collection.mutable.LinkedList(2))
  p(s"LikedList:$list2")

  p("-=-=-=-=-=-=-=-=-=-Map-=-=-=-=-=-=-=-=-=-=-")

  val map = Map("1" -> "One")
  import scala.collection.mutable.{ Map => MMap }
  val mMap = MMap(map.toSeq: _*)
  val mMap2 = MMap[String, String]() ++= map
  p("-=-=-=-" + mMap)
  p("-=-=-=-" + mMap2)

  p(List(("a", 123), ("b" ,456), ("a", 789)).groupBy(_._1).map { case (k, values) => k -> values.map(_._2) })
  p(List(("a", 123), ("b" ,456), ("a", 789)).groupBy(_._1).mapValues(_.map(_._2)))

  val list2Map = (MMap[String, List[Int]]().withDefaultValue(Nil) /: List(("a", 123), ("b", 456), ("a", 789))) {
    case (m, (k, v)) => m.get(k) match {
      case Some(vl) => m + (k -> (v :: vl))
      case None => m + (k -> (v :: Nil))
    }
  }
  p("list2Map:" + list2Map)

  p("-=-=-=-=-Function.unlift(a.andThen(b.lift))-=-=-=-=-=-")

  //  val editDealerInfo: PartialFunction[String, String] = {
  //    case "admin" =>
  //  }

  def andThen2[A, B, C](f: PartialFunction[A, B], g: PartialFunction[B, C]): PartialFunction[A, C] = Function.unlift(f.andThen(g.lift))

  def as(a: Int)(b: Int, c: Int): Int = { a + b + c }
  //> as: (a: Int)(b: Int, c: Int)Int
  def shortA = as _ //> shortA: => Int => ((Int, Int) => Int)
  def plusAWith1 = shortA.andThen { v =>
      v.tupled.andThen { _ + 1 }
    } //> plusAWith1: => Int => (((Int, Int)) => Int)

  println(plusAWith1(1)(2, 3)) //> 7

  val g: Int => Int = _ + 1 //> g  : Int => Int = <function1>

  val fun1 = as _ compose g //> fun1  : Int => ((Int, Int) => Int) = <function1>
  fun1(1)(2, 3) //> res1: Int = 7


}
